home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 9 / FM Towns Free Software Collection 9.iso / t_os / shell / tsbgex / src / neko / neko.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  21.8 KB  |  816 lines

  1. /*
  2.  * neko for TownsOS
  3.  *
  4.  *   Original = xneko by Masayuki Koba
  5.  */
  6.  
  7. #include "neko.h"
  8.  
  9. #define TIMER            5
  10.  
  11. /* 4bit color */
  12. #define    WINDOW_WIDTH4        320    /* ウィンドウの幅 (ピクセル) */
  13. #define    WINDOW_HEIGHT4        320    /* ウィンドウの高さ (ピクセル) */
  14. #define    DEFAULT_WIN_X4        160    /* ウィンドウ生成X座標 */
  15. #define    DEFAULT_WIN_Y4        100    /* ウィンドウ生成Y座標 */
  16. #define    NEKO_SPEED4            16
  17. /* 16bit color */
  18. #define    WINDOW_WIDTH16        200    /* ウィンドウの幅 (ピクセル) */
  19. #define    WINDOW_HEIGHT16        180    /* ウィンドウの高さ (ピクセル) */
  20. #define    DEFAULT_WIN_X16        60    /* ウィンドウ生成X座標 */
  21. #define    DEFAULT_WIN_Y16        40    /* ウィンドウ生成Y座標 */
  22. #define    NEKO_SPEED16        8
  23.  
  24. #define    MAX_TICK        9999        /* Odd Only! */
  25. #define    IDLE_SPACE        6
  26.  
  27. /* config */
  28. int timer = TIMER;
  29.  
  30. int speed16 = NEKO_SPEED4;
  31. int x16 = DEFAULT_WIN_X4;
  32. int y16 = DEFAULT_WIN_Y4;
  33. int w16 = WINDOW_WIDTH4;
  34. int h16 = WINDOW_HEIGHT4;
  35. int frame16 = TRUE;
  36. int col16fc = FALSE;
  37. int col16_f = 1;
  38. int col16_c = FALSE;
  39. int col16_0 = 1;
  40. int col16_1 = 15;
  41. int col32k0 = 0x0000;
  42. int col32k1 = 0x7fff;
  43.  
  44. int speed32k = NEKO_SPEED16;
  45. int x32k = DEFAULT_WIN_X16;
  46. int y32k = DEFAULT_WIN_Y16;
  47. int w32k = WINDOW_WIDTH16;
  48. int h32k = WINDOW_HEIGHT16;
  49. int frame32k = TRUE;
  50.  
  51. /* 猫の状態定数 */
  52. #define    NEKO_STOP        0    /* 立ち止まった */
  53. #define    NEKO_JARE        1    /* 顔を洗っている */
  54. #define    NEKO_KAKI        2    /* 頭を掻いている */
  55. #define    NEKO_AKUBI        3    /* あくびをしている */
  56. #define    NEKO_SLEEP        4    /* 寝てしまった */
  57. #define    NEKO_AWAKE        5    /* 目が覚めた */
  58. #define    NEKO_U_MOVE        6    /* 上に移動中 */
  59. #define    NEKO_D_MOVE        7    /* 下に移動中 */
  60. #define    NEKO_L_MOVE        8    /* 左に移動中 */
  61. #define    NEKO_R_MOVE        9    /* 右に移動中 */
  62. #define    NEKO_UL_MOVE        10    /* 左上に移動中 */
  63. #define    NEKO_UR_MOVE        11    /* 右上に移動中 */
  64. #define    NEKO_DL_MOVE        12    /* 左下に移動中 */
  65. #define    NEKO_DR_MOVE        13    /* 右下に移動中 */
  66. #define    NEKO_U_TOGI        14    /* 上の壁を引っ掻いている */
  67. #define    NEKO_D_TOGI        15    /* 下の壁を引っ掻いている */
  68. #define    NEKO_L_TOGI        16    /* 左の壁を引っ掻いている */
  69. #define    NEKO_R_TOGI        17    /* 右の壁を引っ掻いている */
  70.  
  71. /* 猫のアニメーション繰り返し回数 */
  72. #define    NEKO_STOP_TIME        4
  73. #define    NEKO_JARE_TIME        10
  74. #define    NEKO_KAKI_TIME        4
  75. #define    NEKO_AKUBI_TIME        3
  76. #define    NEKO_AWAKE_TIME        3
  77. #define    NEKO_TOGI_TIME        10
  78.  
  79. #define SinPiPer8Times3    853    /* sin( 3π/8 )2×1000 */
  80. #define SinPiPer8        146    /* sin( π/8 )2×1000 */
  81.  
  82. /*
  83.  *    グローバル変数
  84.  */
  85. u_int BlackPixel, WhitePixel;
  86.  
  87. int WindowWidth;
  88. int WindowHeight;
  89. int WindowPointX;
  90. int WindowPointY;
  91.  
  92. int            NekoTickCount;        /* 猫動作カウンタ */
  93. int            NekoStateCount;        /* 猫同一状態カウンタ */
  94. int            NekoState;        /* 猫の状態 */
  95. int            NekoX;            /* 猫X座標 */
  96. int            NekoY;            /* 猫Y座標 */
  97. int            NekoMoveDx;        /* 猫移動距離X */
  98. int            NekoMoveDy;        /* 猫移動距離Y */
  99. int            NekoLastX;        /* 猫最終描画X座標 */
  100. int            NekoLastY;        /* 猫最終描画Y座標 */
  101. int            NekoSpeed;
  102.  
  103. int            MouseX;            /* マウスX座標 */
  104. int            MouseY;            /* マウスY座標 */
  105. int            PrevMouseX = 0;        /* 直前のマウスX座標 */
  106. int            PrevMouseY = 0;        /* 直前のマウスY座標 */
  107.  
  108. /*
  109.  * bitmaps
  110.  */
  111. #define    BITMAP_WIDTH        32    /* 1キャラクタの幅 (ピクセル) */
  112. #define    BITMAP_HEIGHT        32    /* 1キャラクタの高さ (ピクセル) */
  113.  
  114. u_char save[BITMAP_WIDTH*BITMAP_HEIGHT*sizeof (short)];
  115.  
  116. #include "bitmaps/icon.xbm"
  117. #include "bitmaps/cursor.xbm"
  118. #include "bitmask/cursor.xbm"
  119.  
  120. #include "bitmaps/space.xbm"
  121.  
  122. #include "bitmaps/mati2.xbm"
  123. #include "bitmaps/jare2.xbm"
  124. #include "bitmaps/kaki1.xbm"
  125. #include "bitmaps/kaki2.xbm"
  126. #include "bitmaps/mati3.xbm"
  127. #include "bitmaps/sleep1.xbm"
  128. #include "bitmaps/sleep2.xbm"
  129.  
  130. #include "bitmaps/awake.xbm"
  131.  
  132. #include "bitmaps/up1.xbm"
  133. #include "bitmaps/up2.xbm"
  134. #include "bitmaps/down1.xbm"
  135. #include "bitmaps/down2.xbm"
  136. #include "bitmaps/left1.xbm"
  137. #include "bitmaps/left2.xbm"
  138. #include "bitmaps/right1.xbm"
  139. #include "bitmaps/right2.xbm"
  140. #include "bitmaps/upright1.xbm"
  141. #include "bitmaps/upright2.xbm"
  142. #include "bitmaps/upleft1.xbm"
  143. #include "bitmaps/upleft2.xbm"
  144. #include "bitmaps/dwleft1.xbm"
  145. #include "bitmaps/dwleft2.xbm"
  146. #include "bitmaps/dwright1.xbm"
  147. #include "bitmaps/dwright2.xbm"
  148.  
  149. #include "bitmaps/utogi1.xbm"
  150. #include "bitmaps/utogi2.xbm"
  151. #include "bitmaps/dtogi1.xbm"
  152. #include "bitmaps/dtogi2.xbm"
  153. #include "bitmaps/ltogi1.xbm"
  154. #include "bitmaps/ltogi2.xbm"
  155. #include "bitmaps/rtogi1.xbm"
  156. #include "bitmaps/rtogi2.xbm"
  157.  
  158.  
  159. #include "bitmask/mati2.xbm"
  160. #include "bitmask/jare2.xbm"
  161. #include "bitmask/kaki1.xbm"
  162. #include "bitmask/kaki2.xbm"
  163. #include "bitmask/mati3.xbm"
  164. #include "bitmask/sleep1.xbm"
  165. #include "bitmask/sleep2.xbm"
  166.  
  167. #include "bitmask/awake.xbm"
  168.  
  169. #include "bitmask/up1.xbm"
  170. #include "bitmask/up2.xbm"
  171. #include "bitmask/down1.xbm"
  172. #include "bitmask/down2.xbm"
  173. #include "bitmask/left1.xbm"
  174. #include "bitmask/left2.xbm"
  175. #include "bitmask/right1.xbm"
  176. #include "bitmask/right2.xbm"
  177. #include "bitmask/upright1.xbm"
  178. #include "bitmask/upright2.xbm"
  179. #include "bitmask/upleft1.xbm"
  180. #include "bitmask/upleft2.xbm"
  181. #include "bitmask/dwleft1.xbm"
  182. #include "bitmask/dwleft2.xbm"
  183. #include "bitmask/dwright1.xbm"
  184. #include "bitmask/dwright2.xbm"
  185.  
  186. #include "bitmask/utogi1.xbm"
  187. #include "bitmask/utogi2.xbm"
  188. #include "bitmask/dtogi1.xbm"
  189. #include "bitmask/dtogi2.xbm"
  190. #include "bitmask/ltogi1.xbm"
  191. #include "bitmask/ltogi2.xbm"
  192. #include "bitmask/rtogi1.xbm"
  193. #include "bitmask/rtogi2.xbm"
  194.  
  195. BitmapData    BitmapDataTable[] =
  196. {
  197. /* 0*/{ space_bits, space_bits, space_width, space_height },
  198. /* 1*/{ mati2_bits, mati2_mask_bits, mati2_width, mati2_height },
  199. /* 2*/{ jare2_bits, jare2_mask_bits, jare2_width, jare2_height },
  200. /* 3*/{ kaki1_bits, kaki1_mask_bits, kaki1_width, kaki1_height },
  201. /* 4*/{ kaki2_bits, kaki2_mask_bits, kaki2_width, kaki2_height },
  202. /* 5*/{ mati3_bits, mati3_mask_bits, mati3_width, mati3_height },
  203. /* 6*/{ sleep1_bits, sleep1_mask_bits, sleep1_width, sleep1_height },
  204. /* 7*/{ sleep2_bits, sleep2_mask_bits, sleep2_width, sleep2_height },
  205. /* 8*/{ awake_bits, awake_mask_bits, awake_width, awake_height },
  206. /* 9*/{ up1_bits, up1_mask_bits, up1_width, up1_height },
  207. /*10*/{ up2_bits, up2_mask_bits, up2_width, up2_height },
  208. /*11*/{ down1_bits, down1_mask_bits, down1_width, down1_height },
  209. /*12*/{ down2_bits, down2_mask_bits, down2_width, down2_height },
  210. /*13*/{ left1_bits, left1_mask_bits, left1_width, left1_height },
  211. /*14*/{ left2_bits, left2_mask_bits, left2_width, left2_height },
  212. /*15*/{ right1_bits, right1_mask_bits, right1_width, right1_height },
  213. /*16*/{ right2_bits, right2_mask_bits, right2_width, right2_height },
  214. /*17*/{ upleft1_bits, upleft1_mask_bits, upleft1_width, upleft1_height },
  215. /*18*/{ upleft2_bits, upleft2_mask_bits, upleft2_width, upleft2_height },
  216. /*19*/{ upright1_bits, upright1_mask_bits, upright1_width, upright1_height },
  217. /*20*/{ upright2_bits, upright2_mask_bits, upright2_width, upright2_height },
  218. /*21*/{ dwleft1_bits, dwleft1_mask_bits, dwleft1_width, dwleft1_height },
  219. /*22*/{ dwleft2_bits, dwleft2_mask_bits, dwleft2_width, dwleft2_height },
  220. /*23*/{ dwright1_bits, dwright1_mask_bits, dwright1_width, dwright1_height },
  221. /*24*/{ dwright2_bits, dwright2_mask_bits, dwright2_width, dwright2_height },
  222. /*25*/{ utogi1_bits, utogi1_mask_bits, utogi1_width, utogi1_height },
  223. /*26*/{ utogi2_bits, utogi2_mask_bits, utogi2_width, utogi2_height },
  224. /*27*/{ dtogi1_bits, dtogi1_mask_bits, dtogi1_width, dtogi1_height },
  225. /*28*/{ dtogi2_bits, dtogi2_mask_bits, dtogi2_width, dtogi2_height },
  226. /*29*/{ ltogi1_bits, ltogi1_mask_bits, ltogi1_width, ltogi1_height },
  227. /*30*/{ ltogi2_bits, ltogi2_mask_bits, ltogi2_width, ltogi2_height },
  228. /*31*/{ rtogi1_bits, rtogi1_mask_bits, rtogi1_width, rtogi1_height },
  229. /*32*/{ rtogi2_bits, rtogi2_mask_bits, rtogi2_width, rtogi2_height },
  230. };
  231.  
  232. typedef struct {
  233.     int TickEven;
  234.     int    TickOdd;
  235. } Animation;
  236.  
  237. Animation    AnimationPattern[] =
  238. {
  239.     { 1, 1 },        /* NekoState == NEKO_STOP */
  240.     { 2, 1 },        /* NekoState == NEKO_JARE */
  241.     { 3, 4 },        /* NekoState == NEKO_KAKI */
  242.     { 5, 5 },        /* NekoState == NEKO_AKUBI */
  243.     { 6, 7 },        /* NekoState == NEKO_SLEEP */
  244.     { 8, 8 },        /* NekoState == NEKO_AWAKE */
  245.     { 9, 10 },        /* NekoState == NEKO_U_MOVE */
  246.     { 11, 12 },        /* NekoState == NEKO_D_MOVE */
  247.     { 13, 14 },        /* NekoState == NEKO_L_MOVE */
  248.     { 15, 16 },        /* NekoState == NEKO_R_MOVE */
  249.     { 17, 18 },        /* NekoState == NEKO_UL_MOVE */
  250.     { 19, 20 },    /* NekoState == NEKO_UR_MOVE */
  251.     { 21, 22 },    /* NekoState == NEKO_DL_MOVE */
  252.     { 23, 24 },    /* NekoState == NEKO_DR_MOVE */
  253.     { 25, 26 },        /* NekoState == NEKO_U_TOGI */
  254.     { 27, 28 },    /* NekoState == NEKO_D_TOGI */
  255.     { 29, 30 },    /* NekoState == NEKO_L_TOGI */
  256.     { 31, 32 },    /* NekoState == NEKO_R_TOGI */
  257. };
  258.  
  259. struct window win, frame_win[4];
  260. int f_win = FALSE;
  261. int neko_win = FALSE;
  262. int neko_first = TRUE;
  263. int neko_count = 1;
  264. u_char frame_save[4][1024];
  265.  
  266. void nekomain()
  267. {
  268.     int i;
  269.     extern int aplid, active, restart, unmapped;
  270.     extern short vramseg;
  271.     extern int pixel, dwidth, vheight;
  272.     extern short _col32k0[], _col32k1[];
  273.     extern void NekoThinkDraw(), SetNekoState();
  274.     extern void DrawWindow4(), DrawWindow16(), FindBlackWhite();
  275.     extern void draw16(), draw4(), draw4f(), draw16f();
  276.     extern void map();
  277.     extern int _setfs();
  278.     
  279.     if (!active)
  280.         return;
  281.  
  282.     /* speed control timer */
  283.     if (--neko_count > 0)
  284.         return;
  285.     neko_count = timer;
  286.  
  287.     _setfs(vramseg);
  288.     if (restart){
  289.         restart = FALSE;
  290.         /* make Frame */
  291.         if (pixel == 4){    /* 4bit-color */
  292.             if (dwidth < 1024){                /* MR */
  293.                 WindowPointX = x16;
  294.                 WindowWidth  = w16;
  295.             } else {
  296.                 WindowPointX = x16 + (x16 >> 1);    /* x 1.5 */
  297.                 WindowWidth  = w16 + (w16 >> 1);
  298.             }
  299.             if (vheight < 1024){
  300.                 WindowPointY = y16;
  301.                 WindowHeight = h16;
  302.             } else {
  303.                 WindowPointY = y16 + (y16 >> 1);
  304.                 WindowHeight = h16 + (h16 >> 1);
  305.             }
  306.             NekoSpeed = speed16;
  307.             FindBlackWhite(TRUE);
  308.             if (!col16_c){
  309.                 col16_0 = BlackPixel;
  310.                 col16_1 = WhitePixel;
  311.             }
  312.             if (!col16fc)
  313.                 col16_f = BlackPixel;
  314.             col16_0 |= col16_0 << 4;
  315.             col16_1 |= col16_1 << 4;
  316.             col16_f |= col16_f << 4;
  317.             for (i = 0; i < 4; i++){
  318.                 frame_win[i].draw = draw4f;
  319.                 frame_win[i].size = WindowHeight;
  320.             }
  321.             win.draw = draw4;
  322.             win.size = BITMAP_WIDTH*BITMAP_HEIGHT;
  323.         } else if (pixel == 16){            /* 15bit-color */
  324.             if (dwidth < 512){        /* MR */
  325.                 WindowPointX = x32k;
  326.                 WindowWidth  = w32k;
  327.             } else {
  328.                 WindowPointX = x32k + (x32k >> 1);
  329.                 WindowWidth  = w32k + (w32k >> 1);
  330.             }
  331.             if (vheight < 512){
  332.                 WindowPointY = y32k;
  333.                 WindowHeight = h32k;
  334.             } else {
  335.                 WindowPointY = y32k + (y32k >> 1);
  336.                 WindowHeight = h32k + (h32k >> 1);
  337.             }
  338.             NekoSpeed = speed32k;
  339.             *_col32k0 = col32k0;
  340.             *_col32k1 = col32k1;
  341.             frame_win[0].draw = frame_win[1].draw = draw16f;
  342.             frame_win[2].draw = frame_win[3].draw = draw16f;
  343.             frame_win[0].size = frame_win[1].size = WindowHeight*sizeof(short);
  344.             frame_win[2].size = frame_win[3].size = WindowWidth*sizeof(short);
  345.             win.draw = draw16;
  346.             win.size = BITMAP_WIDTH*BITMAP_HEIGHT*sizeof (short);
  347.         } else
  348.             return;
  349.             
  350.         /* 猫の初期化 */
  351.         NekoX = ( WindowWidth - BITMAP_WIDTH / 2 ) / 2;
  352.         NekoY = ( WindowHeight - BITMAP_HEIGHT / 2 ) / 2;
  353.         NekoLastX = NekoX;
  354.         NekoLastY = NekoY;
  355.         SetNekoState( NEKO_STOP );
  356.         
  357.         win.x = WindowPointX + NekoX;
  358.         win.y = WindowPointY + NekoY;
  359.         win.w = BITMAP_WIDTH;
  360.         win.h = BITMAP_HEIGHT;
  361.         win.save = save;
  362.         win.owner = NULL;
  363.         win.aplid = aplid;
  364.         win.mapped = FALSE;
  365.         frame_win[0].x = frame_win[2].x = frame_win[3].x = WindowPointX;
  366.         frame_win[1].x = WindowPointX + WindowWidth;
  367.         frame_win[0].y = frame_win[1].y = frame_win[2].y = WindowPointY;
  368.         frame_win[3].y = WindowPointY + WindowHeight;
  369.         frame_win[0].w = frame_win[1].w = 1;
  370.         frame_win[2].w = frame_win[3].w = WindowWidth;
  371.         frame_win[0].h = frame_win[1].h = WindowHeight;
  372.         frame_win[2].h = frame_win[3].h = 1;
  373.         for (i = 0; i < 4; i++){
  374.             frame_win[i].save = frame_save[i];
  375.             frame_win[i].owner = NULL;
  376.             frame_win[i].aplid = aplid;
  377.             frame_win[i].mapped = FALSE;
  378.         }
  379.         if (neko_first){
  380.             neko_first = FALSE;
  381.             winCreate(&win);
  382.             if ((pixel == 4  &&  frame16) || (pixel == 16  &&  frame32k)){
  383.                 f_win = TRUE;
  384.                 for (i = 0; i < 4; i++){
  385.                     winCreate(&frame_win[i]);
  386.                     winLower(&frame_win[i]);
  387.                 }
  388.             }
  389.             neko_win = TRUE;
  390.         }
  391.         map(TRUE);
  392.     }
  393.     if (unmapped)
  394.         map(TRUE);
  395.  
  396.     NekoThinkDraw();
  397. }
  398.  
  399. void map(int map)
  400. {
  401.     int i;
  402.     extern int unmapped;
  403.  
  404.     if (map){
  405.         if (neko_win)
  406.             winMap(&win);
  407.         if (f_win){
  408.             for (i = 0; i < 4; i++)
  409.                 winMap(&frame_win[i]);
  410.         }
  411.     } else {
  412.         if (neko_win)
  413.             winUnmap(&win);
  414.         if (f_win){
  415.             for (i = 0; i < 4; i++)
  416.                 winUnmap(&frame_win[i]);
  417.         }
  418.     }
  419.     unmapped = !map;
  420. }
  421.  
  422. void terminate()
  423. {
  424.     int i;
  425.  
  426.     if (neko_win){
  427.         winUnmap(&win);
  428.         winDestroy(&win);
  429.         neko_win = FALSE;
  430.     }
  431.     if (f_win){
  432.         for (i = 0; i < 4; i++){
  433.             winUnmap(&frame_win[i]);
  434.             winDestroy(&frame_win[i]);
  435.         }
  436.         f_win = FALSE;
  437.     }
  438. }
  439.  
  440. /*--------------------------------------------------------------
  441.  *
  442.  *    動作解析猫描画処理
  443.  *
  444.  *--------------------------------------------------------------*/
  445. void
  446. NekoThinkDraw()
  447. {
  448.     extern void CalcDxDy(), DrawNeko(), TickCount(), SetNekoState();
  449.     extern void NekoDirection();
  450.     extern int IsNekoMoveStart(), IsWindowOver(), IsNekoDontMove();
  451.     
  452.     CalcDxDy();
  453.  
  454.     if ( NekoState != NEKO_SLEEP ) {
  455.         DrawNeko( NekoX, NekoY,
  456.               NekoTickCount % 2 == 0 ?  
  457.               AnimationPattern[ NekoState ].TickEven :
  458.               AnimationPattern[ NekoState ].TickOdd );
  459.     } else {
  460.         DrawNeko( NekoX, NekoY,
  461.               NekoTickCount % 8 <= 3 ?
  462.               AnimationPattern[ NekoState ].TickEven :
  463.               AnimationPattern[ NekoState ].TickOdd );
  464.     }
  465.  
  466.     TickCount();
  467.  
  468.     switch ( NekoState ) {
  469.     case NEKO_STOP:
  470.         if ( IsNekoMoveStart() ) {
  471.             SetNekoState( NEKO_AWAKE );
  472.             break;
  473.         }
  474.         if ( NekoStateCount < NEKO_STOP_TIME ) {
  475.             break;
  476.         }
  477.         if ( NekoMoveDx < 0 && NekoX <= 0 ) {
  478.             SetNekoState( NEKO_L_TOGI );
  479.         } else if ( NekoMoveDx > 0 && NekoX >= WindowWidth - BITMAP_WIDTH ) {
  480.             SetNekoState( NEKO_R_TOGI );
  481.         } else if ( NekoMoveDy < 0 && NekoY <= 0 ) {
  482.             SetNekoState( NEKO_U_TOGI );
  483.         } else if ( NekoMoveDy > 0 && NekoY >= WindowHeight - BITMAP_HEIGHT ) {
  484.             SetNekoState( NEKO_D_TOGI );
  485.         } else {
  486.             SetNekoState( NEKO_JARE );
  487.         }
  488.         break;
  489.     case NEKO_JARE:
  490.         if ( IsNekoMoveStart() ) {
  491.             SetNekoState( NEKO_AWAKE );
  492.             break;
  493.         }
  494.         if ( NekoStateCount < NEKO_JARE_TIME ) {
  495.             break;
  496.         }
  497.         SetNekoState( NEKO_KAKI );
  498.         break;
  499.     case NEKO_KAKI:
  500.         if ( IsNekoMoveStart() ) {
  501.             SetNekoState( NEKO_AWAKE );
  502.             break;
  503.         }
  504.         if ( NekoStateCount < NEKO_KAKI_TIME ) {
  505.             break;
  506.         }
  507.         SetNekoState( NEKO_AKUBI );
  508.         break;
  509.     case NEKO_AKUBI:
  510.         if ( IsNekoMoveStart() ) {
  511.             SetNekoState( NEKO_AWAKE );
  512.             break;
  513.         }
  514.         if ( NekoStateCount < NEKO_AKUBI_TIME ) {
  515.             break;
  516.         }
  517.         SetNekoState( NEKO_SLEEP );
  518.         break;
  519.     case NEKO_SLEEP:
  520.         if ( IsNekoMoveStart() ) {
  521.             SetNekoState( NEKO_AWAKE );
  522.             break;
  523.         }
  524.         break;
  525.     case NEKO_AWAKE:
  526.         if ( NekoStateCount < NEKO_AWAKE_TIME ) {
  527.             break;
  528.         }
  529.         NekoDirection();    /* 猫が動く向きを求める */
  530.         break;
  531.     case NEKO_U_MOVE:
  532.     case NEKO_D_MOVE:
  533.     case NEKO_L_MOVE:
  534.     case NEKO_R_MOVE:
  535.     case NEKO_UL_MOVE:
  536.     case NEKO_UR_MOVE:
  537.     case NEKO_DL_MOVE:
  538.     case NEKO_DR_MOVE:
  539.         NekoX += NekoMoveDx;
  540.         NekoY += NekoMoveDy;
  541.         NekoDirection();
  542.         if ( IsWindowOver() ) {
  543.             if ( IsNekoDontMove() ) {
  544.                 SetNekoState( NEKO_STOP );
  545.             }
  546.         }
  547.         break;
  548.     case NEKO_U_TOGI:
  549.     case NEKO_D_TOGI:
  550.     case NEKO_L_TOGI:
  551.     case NEKO_R_TOGI:
  552.         if ( IsNekoMoveStart() ) {
  553.             SetNekoState( NEKO_AWAKE );
  554.             break;
  555.         }
  556.         if ( NekoStateCount < NEKO_TOGI_TIME ) {
  557.             break;
  558.         }
  559.         SetNekoState( NEKO_KAKI );
  560.         break;
  561.     default:
  562.         /* Internal Error */
  563.         SetNekoState( NEKO_STOP );
  564.         break;
  565.     }
  566. }
  567.  
  568. /*--------------------------------------------------------------
  569.  *
  570.  *    猫移動 dx, dy 計算
  571.  *
  572.  *--------------------------------------------------------------*/
  573. void
  574. CalcDxDy()
  575. {
  576.     short x, y;
  577.     int LargeX, LargeY;
  578.     extern int pixel;
  579.     extern void _mousepos();
  580.  
  581.     PrevMouseX = MouseX;
  582.     PrevMouseY = MouseY;
  583.     
  584.     _mousepos(&x, &y);
  585.     if (pixel == 16){
  586.         x >>= 1;
  587.         y >>= 1;
  588.     }
  589.     MouseX = x - WindowPointX;
  590.     MouseY = y - WindowPointY;
  591.  
  592.     LargeX = MouseX - (NekoX + BITMAP_WIDTH / 2);
  593.     LargeY = MouseY - (NekoY + BITMAP_HEIGHT / 2);
  594.     
  595.        if (LargeX >= 0)
  596.             NekoMoveDx = (LargeX < NekoSpeed) ? LargeX : NekoSpeed;
  597.        else
  598.             NekoMoveDx = (-NekoSpeed < LargeX) ? LargeX : -NekoSpeed;
  599.        if (LargeY >= 0)
  600.             NekoMoveDy = (LargeY < NekoSpeed) ? LargeY : NekoSpeed;
  601.        else
  602.             NekoMoveDy = (-NekoSpeed < LargeY) ? LargeY : -NekoSpeed;
  603. }
  604.  
  605. /*--------------------------------------------------------------
  606.  *
  607.  *    ティックカウント処理
  608.  *
  609.  *--------------------------------------------------------------*/
  610. void
  611. TickCount()
  612. {
  613.     if ( ++NekoTickCount >= MAX_TICK ) {
  614.         NekoTickCount = 0;
  615.     }
  616.  
  617.     if ( NekoTickCount % 2 == 0 ) {
  618.         if ( NekoStateCount < MAX_TICK ) {
  619.             NekoStateCount++;
  620.         }
  621.     }
  622. }
  623.  
  624. /*--------------------------------------------------------------
  625.  *
  626.  *    猫状態設定
  627.  *
  628.  *--------------------------------------------------------------*/
  629. void
  630. SetNekoState(int SetValue)
  631. {
  632.     NekoTickCount = 0;
  633.     NekoStateCount = 0;
  634.  
  635.     NekoState = SetValue;
  636. }
  637.  
  638.  
  639. /*--------------------------------------------------------------
  640.  *
  641.  *    猫移動方法決定
  642.  *
  643.  *--------------------------------------------------------------*/
  644. void
  645. NekoDirection()
  646. {
  647.     int            NewState;
  648.     int LargeX, LargeY, LargeY2;
  649.     int Length2;
  650.     int SinTheta2;
  651.  
  652.     if (NekoMoveDx == 0  &&  NekoMoveDy == 0){
  653.         NewState = NEKO_STOP;
  654.     } else {
  655.         LargeX = NekoMoveDx;
  656.         LargeY = -NekoMoveDy;
  657.         LargeY2 = LargeY * LargeY * 1000;
  658.         if (LargeY < 0)
  659.             LargeY2 = -LargeY2;
  660.         Length2 = LargeX * LargeX + LargeY * LargeY;
  661.         SinTheta2 = LargeY2 / Length2;
  662.  
  663.         if (NekoMoveDx > 0){
  664.             if (SinTheta2 > SinPiPer8Times3){
  665.                 NewState = NEKO_U_MOVE;
  666.             } else if ((SinTheta2 <= SinPiPer8Times3)
  667.                 && (SinTheta2 > SinPiPer8)){
  668.                 NewState = NEKO_UR_MOVE;
  669.             } else if ((SinTheta2 <= SinPiPer8)
  670.                 && (SinTheta2 > -(SinPiPer8))){
  671.                 NewState = NEKO_R_MOVE;
  672.             } else if ((SinTheta2 <= -(SinPiPer8))
  673.                 && (SinTheta2 > -(SinPiPer8Times3))){
  674.                 NewState = NEKO_DR_MOVE;
  675.             } else {
  676.                 NewState = NEKO_D_MOVE;
  677.             }
  678.         } else {
  679.             if (SinTheta2 > SinPiPer8Times3){
  680.                 NewState = NEKO_U_MOVE;
  681.             } else if ((SinTheta2 <= SinPiPer8Times3)
  682.                 && (SinTheta2 > SinPiPer8)){
  683.                 NewState = NEKO_UL_MOVE;
  684.             } else if ((SinTheta2 <= SinPiPer8)
  685.                 && (SinTheta2 > -(SinPiPer8))){
  686.                 NewState = NEKO_L_MOVE;
  687.             } else if ((SinTheta2 <= -(SinPiPer8))
  688.                 && (SinTheta2 > -(SinPiPer8Times3))){
  689.                 NewState = NEKO_DL_MOVE;
  690.             } else {
  691.                 NewState = NEKO_D_MOVE;
  692.             }
  693.         }
  694.     }
  695.  
  696.     if (NekoState != NewState){
  697.         SetNekoState( NewState );
  698.     }
  699. }
  700.  
  701.  
  702. /*--------------------------------------------------------------
  703.  *
  704.  *    猫壁ぶつかり判定
  705.  *
  706.  *--------------------------------------------------------------*/
  707. IsWindowOver()
  708. {
  709.     int    ReturnValue = FALSE;
  710.  
  711.     if ( NekoY <= 0 ) {
  712.         NekoY = 0;
  713.         ReturnValue = TRUE;
  714.     } else if ( NekoY >= WindowHeight - BITMAP_HEIGHT ) {
  715.         NekoY = WindowHeight - BITMAP_HEIGHT;
  716.         ReturnValue = TRUE;
  717.     }
  718.     if ( NekoX <= 0 ) {
  719.         NekoX = 0;
  720.         ReturnValue = TRUE;
  721.     } else if ( NekoX >= WindowWidth - BITMAP_WIDTH ) {
  722.         NekoX = WindowWidth - BITMAP_WIDTH;
  723.         ReturnValue = TRUE;
  724.     }
  725.  
  726.     return( ReturnValue );
  727. }
  728.  
  729.  
  730. /*--------------------------------------------------------------
  731.  *
  732.  *    猫移動状況判定
  733.  *
  734.  *--------------------------------------------------------------*/
  735. IsNekoDontMove()
  736. {
  737.     if ( NekoX == NekoLastX && NekoY == NekoLastY ) {
  738.         return( TRUE );
  739.     } else {
  740.         return( FALSE );
  741.     }
  742. }
  743.  
  744.  
  745. /*--------------------------------------------------------------
  746.  *
  747.  *    猫移動開始判定
  748.  *
  749.  *--------------------------------------------------------------*/
  750. IsNekoMoveStart()
  751. {
  752.     if ( ( PrevMouseX >= MouseX - IDLE_SPACE
  753.      && PrevMouseX <= MouseX + IDLE_SPACE ) &&
  754.      ( PrevMouseY >= MouseY - IDLE_SPACE 
  755.      && PrevMouseY <= MouseY + IDLE_SPACE ) ) {
  756.         return( FALSE );
  757.     } else {
  758.         return( TRUE );
  759.     }
  760. }
  761.  
  762. /*--------------------------------------------------------------
  763.  *
  764.  *    猫描画処理
  765.  *
  766.  *--------------------------------------------------------------*/
  767. int neko_id;
  768.  
  769. void
  770. DrawNeko(int x, int y, int id)
  771. {
  772.     neko_id = id;
  773.     if (x != NekoLastX || y != NekoLastY){
  774.          winMove(&win, WindowPointX + x, WindowPointY + y);
  775.      } else {
  776.          winUpdate(&win);
  777.      }
  778.     NekoLastX = x;
  779.     NekoLastY = y;
  780. }
  781.  
  782. struct cell {
  783.     int index;
  784.     u_char color[4];
  785. };
  786.  
  787. struct colorPallet {
  788.     int    n_color;
  789.     struct cell cells[16];
  790. };
  791.  
  792. void FindBlackWhite(int tiff)
  793. {
  794.     struct colorPallet pallet;
  795.     int dark, blight, y;
  796.     u_int n;
  797.     extern void _getpallet();
  798.     
  799.     _getpallet(&pallet);
  800.     dark = 100000; blight = -1;
  801.     n= (tiff) ? 0 : 1;
  802.     for (; n < 16; n++){
  803.         y = (pallet.cells[n].color[0] & 0xf0) 
  804.             + (pallet.cells[n].color[1] & 0xf0)
  805.             + (pallet.cells[n].color[2] & 0xf0);
  806.         if (y < dark){
  807.             dark =y;
  808.             BlackPixel = n;
  809.         }
  810.         if (y > blight){
  811.             blight = y;
  812.             WhitePixel = n;
  813.         }
  814.     }
  815. }
  816.